#include "cheetah/graphics/render_device_fbo.h"

#include "cheetah/graphics/texture_gl.h"
#include "cheetah/graphics/render_buffer.h"
#include "cheetah/core/error.h"

namespace cheetah {
namespace graphics {
using namespace core;
GLint RenderDeviceFBO::s_viewport[4];

void RenderDeviceFBO::SetRenderTarget(const Texture2D *texture) {
  fbo_.UnattachAllColorAttachement();
  fbo_.AttachTexture(texture->target(), texture->tex_id());
}
void RenderDeviceFBO::SetRenderTargets(
    int target_count, const Texture2D *const textures[]) {
  int max_count = FramebufferObject::GetMaxColorAttachments(); 
  if (target_count > max_count) {
    Error("RenderDeviceFBO::SetRenderTargetGL, only %d color attachment \
        is supported", max_count);
    return;
  }
  fbo_.UnattachAllColorAttachement();
  for (int i = 0; i < target_count; ++i) {
    fbo_.AttachTexture(textures[i]->target(), textures[i]->tex_id(), 
                       GL_COLOR_ATTACHMENT0_EXT + i);
  }
}

void RenderDeviceFBO::SetRenderTarget(const RenderBuffer *render_buffer) {
  fbo_.AttachRenderBuffer(render_buffer->buffer_id());
}
void RenderDeviceFBO::SetRenderTargets(
    int target_count, const RenderBuffer *const render_buffers[]) {
  int max_count = FramebufferObject::GetMaxColorAttachments(); 
  if (target_count > max_count) {
    Error("RenderDeviceFBO::SetRenderTargetGL, only %d color attachment \
        is supported", max_count);
    return;
  }
  fbo_.UnattachAllColorAttachement();
  for (int i = 0; i < target_count; ++i) {
    fbo_.AttachRenderBuffer(render_buffers[i]->buffer_id(),
                            GL_COLOR_ATTACHMENT0_EXT + i);
  }
}

void RenderDeviceFBO::SetDepthBuffer(const Texture2D *texture) {
  fbo_.AttachTexture(texture->target(), texture->tex_id(), 
                     GL_DEPTH_ATTACHMENT_EXT);
}
void RenderDeviceFBO::SetDepthBuffer(const RenderBuffer *render_buffer) {
  fbo_.AttachRenderBuffer(render_buffer->buffer_id(), GL_DEPTH_ATTACHMENT_EXT);
}
void RenderDeviceFBO::DisableDepthBuffer() {
  fbo_.Unattach(GL_DEPTH_ATTACHMENT_EXT);
}

void RenderDeviceFBO::SaveMVP() {
  glGetIntegerv(GL_VIEWPORT, s_viewport);
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
}
void RenderDeviceFBO::RestoreMVP() {
  glViewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();
}

} // graphics
} // cheetah

